package org.redmagic.resolver;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.redmagic.common.Hierarchy;
import org.redmagic.common.MagicProperty;
import org.redmagic.common.MagicRequest;
import org.redmagic.common.MagicResponse;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.RestTemplate;

public class WebResolver implements Resolver {

    private final ConcurrentHashMap<String, MagicProperty> cache;
    private final String url;
    private final String group;
    private final Hierarchy hierarchy;
    private final RestTemplate template;
    
    public WebResolver(String url, Hierarchy hierarchy) {
        this(url, "public", hierarchy);
    }
    
    public WebResolver(String url, String group, Hierarchy hierarchy) {
        this.cache = new ConcurrentHashMap<String, MagicProperty>();
        this.url = url;
        this.group = group;
        this.hierarchy = hierarchy;
        this.template = createTemplate();
    }
    
    private RestTemplate createTemplate() {
        RestTemplate restTemplate = new RestTemplate();
        List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
        messageConverters.add(new MappingJackson2HttpMessageConverter());
        restTemplate.setMessageConverters(messageConverters);
        return restTemplate;
    }

    @Override
    public Set<MagicProperty> resolve(Set<String> placeholders) {
        Set<MagicProperty> resolvedProperties = new HashSet<MagicProperty>();
        Set<String> unresolvedPlaceholders = new HashSet<String>(placeholders);
        
        for (String placeholder : placeholders) {
            
            if (this.cache.containsKey(placeholder)) {
                resolvedProperties.add(this.cache.get(placeholder));
                unresolvedPlaceholders.remove(placeholder);
            }
        }
        
        if (!unresolvedPlaceholders.isEmpty()) {
            MagicResponse response = queryForPlaceholders(unresolvedPlaceholders);
            resolvedProperties.addAll(response.getResolvedProperties());
        }
        
        return resolvedProperties;
    }

    private MagicResponse queryForPlaceholders(Set<String> unresolvedPlaceholders) {
        MagicRequest request = new MagicRequest(this.hierarchy, unresolvedPlaceholders, this.group);
        MagicResponse response = this.template.postForObject(this.url, request, MagicResponse.class);
        return response;
    }
}